/*
 * Copyright (c) 2011 Imre Fazekas.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the name of the Brillien nor the names of its
 * terms and concepts may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.vii.brillien.core.component.server;


import com.vii.brillien.core.management.BrillienServices;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.logging.Level;

import static com.vii.brillien.ignition.BrillienContext.*;

/**
 * Service class to handle JMX-based functionality
 */
public class JMXServices {

    public static Registry              registry;
    public static MBeanServer           mbs;
    public static JMXServiceURL         url;
    public static JMXConnectorServer    cs;

    private static final String         LIAISON_JMX_NAME;

    static{
        LIAISON_JMX_NAME = "com.vii.brillien.core.services.server.management:type=Liaison";
    }

    /**
     * Starts JMX services of Brillien
     * Called while initializing Brillien application server
     */
    public static void startJMXServices(){

        try {
            registry = LocateRegistry.createRegistry( JMX_SERVICE_PORT );

            mbs = MBeanServerFactory.createMBeanServer();

            url = new JMXServiceURL(
                "service:jmx:rmi:///jndi/rmi://localhost:" + JMX_SERVICE_PORT + "/" + SERVER_NAME
            );

            cs = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs);

            cs.start();

            systemLog( Level.CONFIG, "\nStart the RMI connector server at:" + JMX_SERVICE_PORT, SERVER_NAME, url.toString() );

            mbs.registerMBean( ManagementFactory.getClassLoadingMXBean(), new ObjectName("java.lang:type=ClassLoading") );
            mbs.registerMBean( ManagementFactory.getMemoryMXBean(), new ObjectName("java.lang:type=Memory") );
            mbs.registerMBean( ManagementFactory.getRuntimeMXBean(), new ObjectName("java.lang:type=Runtime") );
            mbs.registerMBean( ManagementFactory.getThreadMXBean(), new ObjectName("java.lang:type=Threading") );

            mbs.registerMBean(
                    BrillienServices.liaison,
                    new ObjectName( LIAISON_JMX_NAME )
            );
            //mbs.registerMBean( ApplicationServices.liaison, new ObjectName("com.vii.brillien.core.components:type=Liaison") );
        } catch (Exception e) {
            //e.printStackTrace();
            exceptionLog( "JMXServices", "startJMXServices", e );            
        }
    }

    /**
     * Stop JMX services of Brillien
     * Called while shutting down Brillien application server
     */
    public static void stopJMXServices(){
        try {
            systemLog( Level.CONFIG, "Stopping JMX Services..." );
            if( mbs != null ){
                mbs.unregisterMBean( new ObjectName(  LIAISON_JMX_NAME ) );

                //registry.close();

                cs.stop();
            }
        } catch (Exception e) {
            //e.printStackTrace();
            exceptionLog( "JMXServices", "stopJMXServices", e );
        }
    }

}
